/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.data.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import edu.cmu.lti.sepia.infra.topic.model.Progress;
import edu.cmu.lti.sepia.infra.topic.model.Topic;
import edu.cmu.lti.sepia.util.ServletUtil;

/**
 * 
 * Manages Progress object in a DB.
 * 
 * @see Progress
 * @author Hideki Shima
 *
 */
public class ProgressDAO {
	
	// called by topic loader
	public static void loadProgress( SQL sql, String table, String tool, Topic topic, int userId ) 
		throws SQLException {

		boolean nv = tool.equals("nv");

		String sql1 = Query.generate( Query.LOAD_PROGRESS1, table );
		String sql2 = Query.generate( Query.LOAD_PROGRESS2, table );
		String query = nv?sql2:sql1;

		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		ps.setString(1, tool);
		ps.setInt(2, topic.getTopicId());
		if (nv) ps.setInt(3, userId);
		
		rs = sql.executeSelect(ps);
		while ( rs.next() ) {
			Progress p = rsToObject(rs);
			topic.setDone( p.isDone() );
		}
		rs.close();
		ps.close();
	}
	
	public static void loadProgress( SQL sql, String table, String tool, List<Topic> topics, int userId )
		throws SQLException {
		//init 
		Map<String,Topic> topicMap = new LinkedHashMap<String,Topic>(topics.size());
		for ( Topic t : topics ) topicMap.put(t.getTopicId()+"", t);
		
		boolean nv = tool.equals("nv");
		
		String sql1 = Query.generate( Query.LOAD_PROGRESS3, table );
		String sql2 = Query.generate( Query.LOAD_PROGRESS4, table );
		String query = nv?sql2:sql1;
				
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		ps.setString(1, tool);
		if (nv) ps.setInt(2, userId);
		rs = sql.executeSelect(ps);
		while ( rs.next() ) {
			Progress p = rsToObject(rs);
			Topic t = topicMap.get( p.getTopicId()+"" );
			if ( t==null ) continue;
			t.setDone( p.isDone() );
		}
		rs.close();
		ps.close();
	}
	
	private static void insertProgress( SQL sql, String table, Progress progress ) throws SQLException {
		if (progress==null) return;
		
		String query = Query.generate( Query.INSERT_PROGRESS, table );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, progress.getTool());
		ps.setInt(2, progress.getTopicId());
		ps.setInt(3, progress.getUserId());
		ps.setInt(4, progress.isDone()?1:0);
		
		sql.execute(ps);
		ps.close();
	}
	
	public static void updateProgress( SQL sql, String table, Progress progress ) throws SQLException {
		if (progress==null) return;
		
		if ( progress.getTool().matches("td|ne") ) {
			deleteProgress( sql, table, progress.getTool(), progress.getTopicId() );
		} else if ( progress.getTool().matches("nv") ) {
			deleteProgress( sql, table, progress.getTool(), progress.getTopicId(), progress.getUserId() );
		}
		insertProgress( sql, table, progress );
	}

	public static void deleteProgressByTopicId( SQL sql, String table, int topicId ) throws SQLException {
		String query = Query.generate( Query.DELETE_PROGRESS_BYTOPIC, table );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setInt(1, topicId);
		sql.execute(ps);
		ps.close();
	}
	
	private static void deleteProgress( SQL sql, String table, String tool, int topicId ) 
		throws SQLException {
		String query = Query.generate( Query.DELETE_PROGRESS1, table );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, tool);
		ps.setInt(2, topicId);
		sql.execute(ps);
		ps.close();
	}
	
	private static void deleteProgress( SQL sql, String table, String tool, int topicId, int userId )
		throws SQLException {
		String query = Query.generate( Query.DELETE_PROGRESS2, table );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, tool);
		ps.setInt(2, topicId);
		ps.setInt(3, userId);
		sql.execute(ps);
		ps.close();
	}
	
	private static Progress rsToObject( ResultSet rs ) throws SQLException {
		Progress progress = new Progress( rs.getString(1), rs.getInt(2),
				rs.getInt(3), rs.getInt(4)==1 );
		return progress;
	}
	
  public static Progress parseRequest( HttpServletRequest request ) {
    if ( request.getParameter("tool")==null ) return null;
    
    ServletUtil s = new ServletUtil( request );
    Progress p = new Progress( 
        s.readString("tool", ""),
        s.readInt("topicId", 0),
        s.readInt("userId", 0),
        s.readInt("isDone", 0)==1
      );
    
    return p;
  }
	
}
